#include<bits/stdc++.h> 
using namespace std;
// 	一个银行由N个服务窗口，每个窗口前有一个黄线将等待区域分成两个区域，对于顾
//	客来说等在线内的规则如下：（1）每个窗口前线内的区域足够容纳M个顾客，所以当
//	N条线都站满的时候，所有之后的人，即第NM+1个人开始都需要等在黄线以外（2）每
//  个顾客在进入黄线区域时会选择最短的那一排，如果有好几排都是最短的，则去往编
//	号最小的窗口 （3）顾客i会花费Ti时间去完成事务，第一批N个顾客都是早上8：00
//	开始办理业务的。   现在给定每个顾客需要花费的时间，我需要准确给出这个顾客几
//	点会完成他的业务。例如某银行有2个窗口，每个窗口可以让2个人进线。现在有5个人
//	分别要花1，2，6，4，3分钟完成业务。早上8点顾客1和顾客2分别在1号和2号窗口办
//	事，顾客3和顾客4在线内1号队伍和2号队伍排队，顾客5在黄线外排队。则8：01分的
//	时候，顾客1完成，顾客3开始办理业务，顾客5进入黄线。8：02分顾客2完成，顾客4
//	开始办业务，随后顾客4在8：06分完成，顾客3在8：07分完成，顾客5在8：10分完成 
//1.每一个输入都包含一个测试用例，每个用例由三个部分组成。第一部分是一行由4个
//	正整数组成的输入，N≤20表示窗口的个数，M≤10表示黄线内的最大容量，K≤1000
//	表示顾客总数，Q≤1000表示所要查询完成时间的顾客的总数
//2.第二部分紧跟着K个正整数，表示K个顾客各自需要花费的时间。 
//3.第三部分是一行由Q个正整数组成的输入，表示需要问完成时间的人，下标为1~K
//4.输出部分为Q行，每一行以HH:MM的格式打印其结束的时间，HH∈[08,17]，MM∈[00,59
//	]。因为银行每天17：00以后关门，所以顾客17：00后就输出Sorry
//5.queue，sort，map 
string timeSet(int minute){	//为了方便起见，比较是否超时都转化为分来做，只有满足输出条件的再通过这个转换函数去按照格式输出 
	int h = minute / 60 + 8;
	int m = minute % 60;
	char s[5];
	sprintf(s,"%02d:%02d",h,m);
	return s;
}
int main(){
	int N,M,K,Q;
	cin>>N>>M>>K>>Q;	//读入NMKQ四个数 
	queue<int> customers[N];	//N个窗口的队伍情况，存放该队伍里顾客的编号 
	queue<int> allcustomers;	//假设银行营业前所有人都排着队，等8点开门后再进入。所以所有顾客先排成一队 
	map<int,int> spend;	//每个人办理业务需要花费的时间 
	map<int,int> start;	//每个人开始办理业务的时间 
	map<int,int> end;	//每个人结束办理业务的时间 
	int time = 0;	//以8：00为基础，17：00为上限，一共540分钟，从0开始往上累加 
	for(int i=1;i<=K;i++){
		int t;
		cin>>t;
		allcustomers.push(i);	//一共K个顾客，先在大门口站着等待银行开业 
		spend[i] = t;	//读入每个顾客办理的时间并存储 
	}
	for(int i = 0;i<M;i++){	//先用队伍把黄线内的区域尽可能填充满 
		for(int j=0;j<N;j++){	//编号从小到大开始一个个填充 
			int now = allcustomers.front();		//从银行大门外的队伍一个个开始放人进来 
			if(customers[j].empty())	//如果第j排是空的，则这个人是这个队伍第一个人，在8点就可以开始办理业务 
			{
				start[now] = 0;
				end[now] = spend[now];
			 } 
			else{	//否则，这个人开始办理业务的时间取决于同队伍前一个人结束的时间 
				int pre = customers[j].back();
				start[now] = end[pre];
				end[now] = start[now] + spend[now];
			}
			customers[j].push(now);	//将这个人排入黄线内的队伍j中 
			allcustomers.pop();	//将这个人从银行大门外的队伍里删去 
			if(allcustomers.empty()) break;	//如果大门外没人了，就没必要再去填充了 
		}
		if(allcustomers.empty()) break;
	}
	while(time<=540&&!allcustomers.empty()){	//只要时间在540分钟内，且大门外还有人 
		for(int i = 0;i<N;i++){	//从第0列队伍开始排查每个队首的人是否完成了业务 
			if(allcustomers.empty()) break;	//如果在排查过程中出现大门外没人了，则直接跳出循环即可。我们不需要真的等所有人业务办完，我们只需要能让人进入队伍，然后直到自己的结束时间即可 
			int now = customers[i].front();	//取出i列队首的人 
			if(time<end[now]) continue;	//如果他结束时间在当前时间之后则跳过排查他 
			else{
//否则。这里需要注意的是，题目说找最短的且编号最小的一列，我们可以这么考虑
//如果在t时刻，银行大门外还有人待机所有队列从编号小到大排查队首，一旦有排
//查到某个人结束了，这个人就立刻被踢出队伍了，那么在这个时候，所有队伍中，
//最短的队伍就肯定是这个队伍， 前面的队伍还是饱满的，后面的队伍即使也有人要
//被踢出去，但是编号没这个队伍小，所以大门外的人进来填充肯定就这个队伍了 
				customers[i].pop();
				int newone = allcustomers.front();
				allcustomers.pop();
				start[newone] = end[customers[i].back()];
				end[newone] = start[newone] + spend[newone];
				customers[i].push(newone);
			}		
		}
		time++;
	}
	for(int i =0;i<Q;i++){
		int check;
		cin>>check;
		//这里的坑是，即使17：00到了，有的人业务还没结束，银行也会为他办理结束再下班的 
		if(end.find(check)!=end.end()&&start[check]<540) cout<<timeSet(end[check])<<endl;
		else cout<<"Sorry"<<endl;
	}
	return 0;
} 
